layui.define(['jquery', 'jquery.ztree.core'], function(exports) {
    layui.link('/static/module/zTreeSelect.css');
    var MOD_NAME = 'zTreeSelect',
        $ = layui.jquery,
        Tree = function() {};
    Tree.prototype.binit = 0;
    Tree.prototype.t = null;
    Tree.prototype.randId = new Date().getTime();
    Tree.render = function(config, show=false) {
        var tree = new Tree();
        var elem = $('#' + config.treeDomId),
            showElem = $('#' + config.treeShowValueDomId);
        var html = '<ul class="ztree selectztree" id="' + config.treeDomId + tree.randId + '" style="width: 100%;"></ul>' +
            '<input type="hidden" class="layui-input tree_input_00001" readonly/>';
        var searchElem = $('#' + config.treeDomId + ' .ztreeSelect_searchinput'),
            treeElem = $('#' + config.treeDomId + ' .tree_input_00001'),
            searchIconElem = $('#' + config.treeDomId + ' .inline_icon');
        if (tree.binit === 0) {
            tree.binit = 1;
            elem.addClass('menuContent layui-anim layui-anim-upbit');
            if (!show) {
                elem.hide();
            }
            if (config.search && config.search.enable) {
                html = '<input type="text" class="ztreeSelect_searchinput" placeholder="搜索"/>' +
                    '<i class="layui-icon layui-icon-loading layui-anim layui-anim-rotate layui-anim-loop inline_icon" style="display:none;"></i> ' + html;
            }
            html = '<div>' + html + '</div>';
            elem.html(html);
            treeElem = $('#' + config.treeDomId + ' .tree_input_00001');
            searchIconElem = $('#' + config.treeDomId + ' .inline_icon');
            if (config.search && config.search.enable) {
                searchElem = $('#' + config.treeDomId + ' .ztreeSelect_searchinput');
                // searchElem.on('input', function (e) {
                //     searchIconElem.css('display', 'unset');
                //     window.clearTimeout($(this).data('timeout'));
                //     $(this).data('timeout', setTimeout(function () {
                //         Tree.render(config);
                //     }, 1000));
                // });
                searchElem.bind('keydown', function(event) {
                    if(event.keyCode === 13) {
                        event.preventDefault();
                        searchIconElem.css('display', 'unset');
                        setTimeout(function() {
                            config.search.keyword = searchElem.val();
                            Tree.render(config, true);
                        }, 50);
                    }
                });
            }
            elem.css('width', showElem.css('width'));
            showElem.attr('readonly', '');
            if (config.name == null) {
                config.name = showElem.attr('name');
            }
            treeElem.attr('name', config.name);
            showElem.removeAttr('name');
            var initValue = elem.attr('data-sel');
            if (initValue) {
                treeElem.attr("value", initValue);
                treeElem.val(initValue);
            }
        }
        var keyword = config.search ? config.search.keyword : null;
        var sc = keyword && keyword !== '';
        var setting = {
            async: sc || (!config.async || !config.async.enable) ? undefined : {
                enable: config.async.enable,
                type: config.async.type,
                url: config.async.url,
                autoParam: config.async.autoParam,
                dataFilter: function(treeId, parentNode, responseData) {
                    var dt = [];
                    if (config.async.dataFilter) {
                        dt = config.async.dataFilter(treeId, parentNode, responseData);
                    }
                    dt.forEach(function(d) {
                        d.descHtml = d.desc;
                    });
                    return dt;
                }
            },
            data: {
                key: {
                    isParent: sc ? undefined : 'expand',
                    name: "descHtml"
                },
                simpleData: sc ? {
                    enable: true,
                    pIdKey: 'parentId',
                    idKey: 'id',
                    rootPId: null
                } : {
                    enable: true,
                    idKey: 'id',
                    rootPId: null
                }
            },
            view: sc ? {
                nameIsHTML: true
            } : undefined,
            callback: {
                onClick: function(e, treeId, treeNode) {
                    var nodes = t.getSelectedNodes(), v = "";
                    nodes.sort(function compare(a,b){return a.id-b.id;});
                    v = config.showFunction ? config.showFunction(nodes) : defaultShowFunction(nodes);
                    showElem.attr("value", v);
                    showElem.val(v);
                    treeElem.attr("value", treeNode.id);
                    treeElem.val(treeNode.id);
                    hideMenu();
                }
            }
        };

        function blNodes(node) {
            var n = node, r = n.desc;
            while (n && n.parentId) {
                n = t.getNodeByParam('id', n.parentId);
                if (n) {
                    r = n.desc + " / " + r;
                }
            }
            return r;
        }

        function defaultShowFunction(nodes) {
            var v = '';
            if (config.showMode && config.showMode === 'full') {
                for (var i=0, l=nodes.length; i<l; i++) {
                    v += blNodes(nodes[i]) + ",";
                }
                if (v.length > 0 ) v = v.substring(0, v.length-1);
            } else {
                for (var i=0, l=nodes.length; i<l; i++) {
                    v += nodes[i].desc + ",";
                }
                if (v.length > 0 ) v = v.substring(0, v.length-1);
            }
            return v;
        }

        showElem.on('focus', function () {
            setTimeout(function() {
                searchElem.focus();
            }, 1);
            showMenu();
        });
        showElem.click(function () {
            setTimeout(function() {
                searchElem.focus();
            }, 1);
            showMenu();
        });
        function showMenu() {
            elem.show();
            $("body").unbind("mousedown", onBodyDown);
            $("body").bind("mousedown", onBodyDown);
        }
        function hideMenu() {
            elem.hide();
            $("body").unbind("mousedown", onBodyDown);
        }
        function onBodyDown(event) {
            if (!(event.target.id === config.treeDomId || $(event.target).parents('#' + config.treeDomId).length>0)) {
                hideMenu();
            }
        }
        if (sc) {
            $.ajax({
                url : config.search.url,
                type: config.search.type,
                data:{ keyword: keyword},
                async : false,
                success:function (data) {
                    if (data.success) {
                        searchElem.val(keyword);
                        var scData = config.search.dataFilter ? config.search.dataFilter(null, null, data) : data;
                        scData.forEach(function(d) {
                            d.descHtml = d.desc.replace(keyword.trim(), '<span style="color:red;margin:0;">' + keyword + '</span>');
                        });
                        $.fn.zTree.init($('#' + config.treeDomId + tree.randId),
                            setting,
                            scData);
                        var zTree = $.fn.zTree.getZTreeObj(config.treeDomId + tree.randId);
                        zTree.expandAll(true);
                        t = $.fn.zTree.getZTreeObj(config.treeDomId + tree.randId);
                        searchIconElem.hide();
                        setTimeout(function() {
                            searchElem.focus();
                        }, 1);
                    }
                }
            });
        } else {
            $.fn.zTree.init($('#' + config.treeDomId + tree.randId), setting);
            t = $.fn.zTree.getZTreeObj(config.treeDomId + tree.randId);
            if (searchIconElem) {
                searchIconElem.hide();
            }
        }
    };
    exports(MOD_NAME, Tree)
});